#region License
// App.xaml.cs
// 
// Copyright (c) 2012 Xoqal.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
// http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#endregion

namespace Shammateh.Win.UI
{
    using System;
    using System.Threading;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Threading;
    using Shammateh.Win.UI.ViewModels;
    using Xoqal.Presentation.Commands;
    using Xoqal.Presentation.ViewModels;

    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="App"/> class.
        /// </summary>
        /// <exception cref="T:System.InvalidOperationException">More than one instance of the <see cref="T:System.Windows.Application"/> class is created per <see cref="T:System.AppDomain"/>.</exception>
        public App()
        {
            DIContainer.RegisterTypes();
            Data.InstallationService.SetupDatabase();

            InitializeCommands();

            this.Startup += this.App_Startup;
            Dispatcher.CurrentDispatcher.UnhandledException += this.App_DispatcherUnhandledException;

            Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("fa-IR");
            Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
            InputLanguageManager.Current.CurrentInputLanguage = Thread.CurrentThread.CurrentUICulture;
        }

        /// <summary>
        /// Gets or sets the synchronize command.
        /// </summary>
        public static ICommand SynchronizeCommand { get; set; }

        /// <summary>
        /// Gets or sets the logout command.
        /// </summary>
        public static ICommand SignOutCommand { get; set; }

        /// <summary>
        /// Navigates the main window.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public static T NavigateMainWindow<T>()
            where T : IViewModel
        {
            T viewModel = ViewModelFactory<T>.Create();
            ((IContainerViewModel)Current.MainWindow.DataContext).ContentViewModel = viewModel;
            return viewModel;
        }

        /// <summary>
        /// Shows the workspace view.
        /// </summary>
        /// <param name="contentViewType">Type of the content view.</param>
        public static object ShowWorkspaceView(Type contentViewType)
        {
            var containerViewModel = Current.MainWindow.DataContext as ContainerViewModel;
            if (containerViewModel != null)
            {
                var mainViewModel = containerViewModel.ContentViewModel as MainViewModel;
                if (mainViewModel != null)
                {
                    return mainViewModel.ShowWorkspaceView(contentViewType);
                }
            }

            return null;
        }

        /// <summary>
        /// Shows the workspace view.
        /// </summary>
        public static T ShowWorkspaceView<T>()
            where T : class, IViewModel
        {
            object workspaceViewModel = ShowWorkspaceView(typeof(T));
            return ((WorkspaceViewModel<T>)workspaceViewModel).ContentViewModel;
        }

        /// <summary>
        /// Initializes the commands.
        /// </summary>
        private static void InitializeCommands()
        {
            SignOutCommand = new RelayCommand(OnSignOutCommandExecute);
        }

        /// <summary>
        /// Called when sign out command executed.
        /// </summary>
        private static void OnSignOutCommandExecute()
        {
            Application.Current.Shutdown();
        }

        /// <summary>
        /// Handles the Startup event of the App control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.StartupEventArgs"/> instance containing the event data.</param>
        private void App_Startup(object sender, StartupEventArgs e)
        {
            var window = new MainWindow
            {
                DataContext = ViewModelFactory<ContainerViewModel>.Create()
            };
            NavigateMainWindow<MainViewModel>();
            window.Show();
        }

        /// <summary>
        /// Handles the DispatcherUnhandledException event of the App control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Threading.DispatcherUnhandledExceptionEventArgs"/> instance containing the event data.</param>
        private void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            string err = "Oops: " + e.Exception.Message;
            MessageBox.Show(err, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            if (e.Exception.InnerException != null)
            {
                MessageBox.Show(e.Exception.InnerException.Message);
            }

            e.Handled = true; // stop exception from bringing down the app
        }
    }
}
